home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / GLUT / progs / examples / glutplane.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  6KB  |  256 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <unistd.h>
  11. #include <math.h>
  12. #include <GL/glut.h>
  13.  
  14. GLboolean moving = GL_FALSE;
  15.  
  16. #define MAX_PLANES 15
  17.  
  18. struct {
  19.   float speed;          /* zero speed means not flying */
  20.   GLfloat red, green, blue;
  21.   float theta;
  22.   float x, y, z, angle;
  23. } planes[MAX_PLANES];
  24.  
  25. #define v3f glVertex3f  /* v3f was the short IRIS GL name for
  26.                            glVertex3f */
  27.  
  28. void
  29. draw(void)
  30. {
  31.   GLfloat red, green, blue;
  32.   int i;
  33.  
  34.   glClear(GL_DEPTH_BUFFER_BIT);
  35.   /* paint black to blue smooth shaded polygon for background */
  36.   glDisable(GL_DEPTH_TEST);
  37.   glShadeModel(GL_SMOOTH);
  38.   glBegin(GL_POLYGON);
  39.   glColor3f(0.0, 0.0, 0.0);
  40.   v3f(-20, 20, -19);
  41.   v3f(20, 20, -19);
  42.   glColor3f(0.0, 0.0, 1.0);
  43.   v3f(20, -20, -19);
  44.   v3f(-20, -20, -19);
  45.   glEnd();
  46.   /* paint planes */
  47.   glEnable(GL_DEPTH_TEST);
  48.   glShadeModel(GL_FLAT);
  49.   for (i = 0; i < MAX_PLANES; i++)
  50.     if (planes[i].speed != 0.0) {
  51.       glPushMatrix();
  52.       glTranslatef(planes[i].x, planes[i].y, planes[i].z);
  53.       glRotatef(290.0, 1.0, 0.0, 0.0);
  54.       glRotatef(planes[i].angle, 0.0, 0.0, 1.0);
  55.       glScalef(1.0 / 3.0, 1.0 / 4.0, 1.0 / 4.0);
  56.       glTranslatef(0.0, -4.0, -1.5);
  57.       glBegin(GL_TRIANGLE_STRIP);
  58.       /* left wing */
  59.       v3f(-7.0, 0.0, 2.0);
  60.       v3f(-1.0, 0.0, 3.0);
  61.       glColor3f(red = planes[i].red, green = planes[i].green,
  62.         blue = planes[i].blue);
  63.       v3f(-1.0, 7.0, 3.0);
  64.       /* left side */
  65.       glColor3f(0.6 * red, 0.6 * green, 0.6 * blue);
  66.       v3f(0.0, 0.0, 0.0);
  67.       v3f(0.0, 8.0, 0.0);
  68.       /* right side */
  69.       v3f(1.0, 0.0, 3.0);
  70.       v3f(1.0, 7.0, 3.0);
  71.       /* final tip of right wing */
  72.       glColor3f(red, green, blue);
  73.       v3f(7.0, 0.0, 2.0);
  74.       glEnd();
  75.       glPopMatrix();
  76.     }
  77.   glutSwapBuffers();
  78. }
  79.  
  80. void
  81. tick_per_plane(int i)
  82. {
  83.   float theta = planes[i].theta += planes[i].speed;
  84.   planes[i].z = -9 + 4 * cos(theta);
  85.   planes[i].x = 4 * sin(2 * theta);
  86.   planes[i].y = sin(theta / 3.4) * 3;
  87.   planes[i].angle = ((atan(2.0) + M_PI_2) * sin(theta) - M_PI_2) * 180 / M_PI;
  88.   if (planes[i].speed < 0.0)
  89.     planes[i].angle += 180;
  90. }
  91.  
  92. void
  93. add_plane(void)
  94. {
  95.   int i;
  96.  
  97.   for (i = 0; i < MAX_PLANES; i++)
  98.     if (planes[i].speed == 0) {
  99.  
  100. #define SET_COLOR(r,g,b) \
  101.     planes[i].red=r; planes[i].green=g; planes[i].blue=b;
  102.  
  103.       switch (random() % 6) {
  104.       case 0:
  105.         SET_COLOR(1.0, 0.0, 0.0);  /* red */
  106.         break;
  107.       case 1:
  108.         SET_COLOR(1.0, 1.0, 1.0);  /* white */
  109.         break;
  110.       case 2:
  111.         SET_COLOR(0.0, 1.0, 0.0);  /* green */
  112.         break;
  113.       case 3:
  114.         SET_COLOR(1.0, 0.0, 1.0);  /* magenta */
  115.         break;
  116.       case 4:
  117.         SET_COLOR(1.0, 1.0, 0.0);  /* yellow */
  118.         break;
  119.       case 5:
  120.         SET_COLOR(0.0, 1.0, 1.0);  /* cyan */
  121.         break;
  122.       }
  123.       planes[i].speed = (random() % 20) * 0.001 + 0.02;
  124.       if (random() & 0x1)
  125.         planes[i].speed *= -1;
  126.       planes[i].theta = ((float) (random() % 257)) * 0.1111;
  127.       tick_per_plane(i);
  128.       if (!moving)
  129.         glutPostRedisplay();
  130.       return;
  131.     }
  132. }
  133.  
  134. void
  135. remove_plane(void)
  136. {
  137.   int i;
  138.  
  139.   for (i = MAX_PLANES - 1; i >= 0; i--)
  140.     if (planes[i].speed != 0) {
  141.       planes[i].speed = 0;
  142.       if (!moving)
  143.         glutPostRedisplay();
  144.       return;
  145.     }
  146. }
  147.  
  148. void
  149. tick(void)
  150. {
  151.   int i;
  152.  
  153.   for (i = 0; i < MAX_PLANES; i++)
  154.     if (planes[i].speed != 0.0)
  155.       tick_per_plane(i);
  156. }
  157.  
  158. void
  159. animate(void)
  160. {
  161.   tick();
  162.   glutPostRedisplay();
  163. }
  164.  
  165. void
  166. visible(int state)
  167. {
  168.   if (state == GLUT_VISIBLE) {
  169.     if (moving)
  170.       glutIdleFunc(animate);
  171.   } else {
  172.     if (moving)
  173.       glutIdleFunc(NULL);
  174.   }
  175. }
  176.  
  177. void
  178. keyboard(unsigned char ch, int x, int y)
  179. {
  180.   switch (ch) {
  181.   case ' ':
  182.     if (!moving) {
  183.       tick();
  184.       glutPostRedisplay();
  185.     }
  186.     break;
  187.   case 27:             /* ESC */
  188.     exit(0);
  189.     break;
  190.   }
  191. }
  192.  
  193. #define ADD_PLANE    1
  194. #define REMOVE_PLANE    2
  195. #define MOTION_ON    3
  196. #define MOTION_OFF    4
  197. #define QUIT        5
  198.  
  199. void
  200. menu(int item)
  201. {
  202.   switch (item) {
  203.   case ADD_PLANE:
  204.     add_plane();
  205.     break;
  206.   case REMOVE_PLANE:
  207.     remove_plane();
  208.     break;
  209.   case MOTION_ON:
  210.     moving = GL_TRUE;
  211.     glutChangeToMenuEntry(3, "Motion off", MOTION_OFF);
  212.     glutIdleFunc(animate);
  213.     break;
  214.   case MOTION_OFF:
  215.     moving = GL_FALSE;
  216.     glutChangeToMenuEntry(3, "Motion", MOTION_ON);
  217.     glutIdleFunc(NULL);
  218.     break;
  219.   case QUIT:
  220.     exit(0);
  221.     break;
  222.   }
  223. }
  224.  
  225. int
  226. main(int argc, char *argv[])
  227. {
  228.   glutInit(&argc, argv);
  229.   /* use multisampling if available */
  230.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);
  231.   glutCreateWindow("glutplane");
  232.   glutDisplayFunc(draw);
  233.   glutKeyboardFunc(keyboard);
  234.   glutVisibilityFunc(visible);
  235.   glutCreateMenu(menu);
  236.   glutAddMenuEntry("Add plane", ADD_PLANE);
  237.   glutAddMenuEntry("Remove plane", REMOVE_PLANE);
  238.   glutAddMenuEntry("Motion", MOTION_ON);
  239.   glutAddMenuEntry("Quit", QUIT);
  240.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  241.   /* setup OpenGL state */
  242.   glClearDepth(1.0);
  243.   glClearColor(0.0, 0.0, 0.0, 0.0);
  244.   glMatrixMode(GL_PROJECTION);
  245.   glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 20);
  246.   glMatrixMode(GL_MODELVIEW);
  247.   /* add three initial random planes */
  248.   srandom(getpid());
  249.   add_plane();
  250.   add_plane();
  251.   add_plane();
  252.   /* start event processing */
  253.   glutMainLoop();
  254.   return 0;             /* ANSI C requires main to return int. */
  255. }
  256.